using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq.Expressions;
using Charisma.MongoDb.Linq.Expressions;

namespace Charisma.MongoDb.Linq
{
  internal sealed class FieldExtractor: MongoExpressionVisitor
  {
    private static readonly ReadOnlyCollection<FieldExpression> empty = new List<FieldExpression>().AsReadOnly();
    private readonly List<FieldExpression> fields = new List<FieldExpression>();
    private bool skipExtraction;

    public override Expression Visit(Expression node)
    {
      return skipExtraction 
        ? node 
        : base.Visit(node);
    }

    public static ReadOnlyCollection<FieldExpression> ExtractFields(Expression e)
    {
      var extractor = new FieldExtractor();
      extractor.Visit(e);
      return extractor.skipExtraction
        ? empty
        : extractor.fields.AsReadOnly();
    }

    protected internal override Expression VisitField(FieldExpression fe)
    {
      fields.Add(fe);
      return fe;
    }

    protected internal override Expression VisitEntity(EntityExpression ee)
    {
      skipExtraction = true;
      return ee;
    }
  }
}